package tech.waterism.service.service;

import tech.waterism.model.dto.ModelOutputSimple;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import tech.waterism.model.DHF;
import tech.waterism.model.LAG_3;
import tech.waterism.model.SMS_3;
import tech.waterism.model.SMS3_LAG3_Pipeline;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 水文模型异步计算服务
 *
 * <p>提供水文模型的异步计算能力，使用线程池并行执行计算任务。</p>
 *
 * <h3>设计特点：</h3>
 * <ul>
 *   <li>使用@Async注解，自动在独立线程中执行</li>
 *   <li>返回CompletableFuture，支持异步结果查询</li>
 *   <li>记录计算耗时，便于性能监控</li>
 *   <li>完善的异常处理</li>
 * </ul>
 *
 * @author 高宇
 * @since 1.0.0
 */
@Slf4j
@Service
public class ModelCalculationService {

    /**
     * 异步执行DHF模型计算
     *
     * @param inputData 模型输入参数
     * @return CompletableFuture包装的ModelOutputSimple结果
     */
    @Async("modelExecutor")
    public CompletableFuture<ModelOutputSimple> calculateDHFAsync(Map<String, Object> inputData) {
        String threadName = Thread.currentThread().getName();
        log.info("[{}] 开始异步DHF模型计算", threadName);
        long startTime = System.currentTimeMillis();

        try {
            // 执行模型计算
            DHF model = new DHF(inputData);
            model.predict();
            
            // 获取标准化输出对象
            ModelOutputSimple output = model.getLastOutput();

            long duration = System.currentTimeMillis() - startTime;
            log.info("[{}] DHF模型计算完成 - 耗时: {}ms", threadName, duration);

            return CompletableFuture.completedFuture(output);

        } catch (IllegalArgumentException e) {
            log.error("[{}] DHF模型参数错误: {}", threadName, e.getMessage());
            return CompletableFuture.failedFuture(e);

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[{}] DHF模型计算失败 - 耗时: {}ms", threadName, duration, e);
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 异步执行SMS_3模型计算
     *
     * @param inputData 模型输入参数
     * @return CompletableFuture包装的ModelOutputSimple结果
     */
    @Async("modelExecutor")
    public CompletableFuture<ModelOutputSimple> calculateSMS3Async(Map<String, Object> inputData) {
        String threadName = Thread.currentThread().getName();
        log.info("[{}] 开始异步SMS_3模型计算", threadName);
        long startTime = System.currentTimeMillis();

        try {
            // 执行模型计算
            SMS_3 model = new SMS_3(inputData);
            model.predict();
            
            // 获取标准化输出对象
            ModelOutputSimple output = model.getLastOutput();

            long duration = System.currentTimeMillis() - startTime;
            log.info("[{}] SMS_3模型计算完成 - 耗时: {}ms", threadName, duration);

            return CompletableFuture.completedFuture(output);

        } catch (IllegalArgumentException e) {
            log.error("[{}] SMS_3模型参数错误: {}", threadName, e.getMessage());
            return CompletableFuture.failedFuture(e);

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[{}] SMS_3模型计算失败 - 耗时: {}ms", threadName, duration, e);
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 异步执行LAG_3模型计算
     *
     * @param inputData 模型输入参数
     * @return CompletableFuture包装的ModelOutputSimple结果
     */
    @Async("modelExecutor")
    public CompletableFuture<ModelOutputSimple> calculateLAG3Async(Map<String, Object> inputData) {
        String threadName = Thread.currentThread().getName();
        log.info("[{}] 开始异步LAG_3模型计算", threadName);
        long startTime = System.currentTimeMillis();

        try {
            // 执行模型计算
            LAG_3 model = new LAG_3(inputData);
            model.predict();
            
            // 获取标准化输出对象
            ModelOutputSimple output = model.getLastOutput();

            long duration = System.currentTimeMillis() - startTime;
            log.info("[{}] LAG_3模型计算完成 - 耗时: {}ms", threadName, duration);

            return CompletableFuture.completedFuture(output);

        } catch (IllegalArgumentException e) {
            log.error("[{}] LAG_3模型参数错误: {}", threadName, e.getMessage());
            return CompletableFuture.failedFuture(e);

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[{}] LAG_3模型计算失败 - 耗时: {}ms", threadName, duration, e);
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 异步执行SMS3_LAG3串联模型计算
     *
     * @param inputData SMS_3模型输入参数（包含SMS_3和LAG_3的参数）
     * @return CompletableFuture包装的ModelOutputSimple结果（LAG_3的输出）
     */
    @Async("modelExecutor")
    public CompletableFuture<ModelOutputSimple> calculateSMS3LAG3PipelineAsync(Map<String, Object> inputData) {
        String threadName = Thread.currentThread().getName();
        log.info("[{}] 开始异步SMS3_LAG3串联模型计算", threadName);
        long startTime = System.currentTimeMillis();

        try {
            // 执行串联模型计算，返回 LAG_3 模型实例
            LAG_3 lag3Model = SMS3_LAG3_Pipeline.runPipelineWithData(inputData);
            
            // 获取 LAG_3 模型的标准化输出对象
            ModelOutputSimple output = lag3Model.getLastOutput();

            long duration = System.currentTimeMillis() - startTime;
            log.info("[{}] SMS3_LAG3串联模型计算完成 - 耗时: {}ms", threadName, duration);

            return CompletableFuture.completedFuture(output);

        } catch (IllegalArgumentException e) {
            log.error("[{}] SMS3_LAG3串联模型参数错误: {}", threadName, e.getMessage());
            return CompletableFuture.failedFuture(e);

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[{}] SMS3_LAG3串联模型计算失败 - 耗时: {}ms", threadName, duration, e);
            return CompletableFuture.failedFuture(e);
        }
    }
}

